package com.example.sys.pay.service;

import com.example.core.mapping.Mapping;
import com.example.core.po.BasePo;
import com.example.core.service.BaseServiceImpl;
import com.example.sys.job.service.SysJobRunTimeService;
import com.example.sys.pay.dao.SysPayDao;
import com.example.sys.pay.mapping.SysPayMapping;
import com.example.sys.pay.po.SysPay;
import com.example.sys.pay.vo.SysPayVo;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.BestPayService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SysPayServiceImpl extends BaseServiceImpl<SysPayDao, SysPay, SysPayVo> implements SysPayService, SysJobRunTimeService {

    @Resource
    private List<ISysPayService> sysPayServices = new ArrayList<>();

    @Resource
    private List<SysPayHandler> sysPayHandlers = new ArrayList<>();

    @Resource
    private BestPayService bestPayService;

    @Value("${pay.title}")
    private String title;

    @Override
    public Class<? extends Mapping> getMappingClass() {
        return SysPayMapping.class;
    }

    @Override
    public PayResponse apply(BasePo po, BestPayTypeEnum payType, Double amount) {
        SysPay sysPay = new SysPay();
        sysPay.setModelId(po.getId());
        sysPay.setModelName(po.getClass().getName());
        sysPay.setFee(amount);
        sysPay.setType(payType.getCode());
        this.save(sysPay);
        return apply(payType, sysPay.getId(), amount);
    }

    @Override
    public PayResponse apply(BestPayTypeEnum payType, String orderId, Double amount) {
        PayRequest request = new PayRequest();
        request.setPayTypeEnum(payType);
        request.setOrderId(orderId);
        request.setOrderAmount(amount);
        request.setOrderName(title);
        return bestPayService.pay(request);
    }

    @Override
    public RefundResponse refund(String orderId) throws Exception {
        return null;
    }

    /****
     *
     * 支付结果回调处理逻辑
     * @param notifyData
     * @return
     * @throws Exception
     */
    @Override
    public String notify(String notifyData) throws Exception {
        logger.warn("支付回调: " + notifyData);
        PayResponse response = bestPayService.asyncNotify(notifyData);
        String id = response.getOrderId();
        SysPay sysPay = getById(id);
        for (ISysPayService sysPayService : this.sysPayServices) {
            sysPayService.payExecute(response, sysPay);
        }
        for (SysPayHandler sysPayHandler : this.sysPayHandlers) {
            if (sysPayHandler.match(response)) {
                return sysPayHandler.response(response);
            }
        }
        throw new RuntimeException("错误的支付平台，请核对并确认.");
    }

    /****
     * 订单过期回调
     * @param modelName
     * @param modelId
     */
    @Override
    public void execute(String modelName, String modelId) {
        if (SysPay.class.getName().equalsIgnoreCase(modelName))
            logger.warn("订单 modelId: " + modelId + " 已经过期，请检查是否完成支付.");
    }
}
